package com.learnyou.server.xingzuo.biz.helper;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.learnyou.server.xingzuo.common.config.BaiduGeoConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.geo.Point;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author heweifeng
 * @Description:
 * @date 2022/12/4 15:57
 */
@Slf4j
public class BaiduGeoHelper {

    private static final String GEO_CODING_URL = "https://api.map.baidu.com/geocoding/v3/";

    public static Point  geoCoding(String address, BaiduGeoConfig baiduGeoConfig){

        Map<String, Object> paramsMap = new LinkedHashMap();
        paramsMap.put("address", address);
        paramsMap.put("output", "json");
        paramsMap.put("ak", baiduGeoConfig.getAk());
        try {
            String paramsStr = toQueryString(paramsMap);
            String wholeStr = new String("/geocoding/v3/?" + paramsStr + baiduGeoConfig.getSk());
            String tempStr = URLEncoder.encode(wholeStr, "UTF-8");
            String sn = MD5(tempStr);
            paramsMap.put("sn", sn);
            String json = HttpUtil.get(GEO_CODING_URL, paramsMap);
            JSONObject jsonObj = JSONUtil.parseObj(json);
            Object status = JSONUtil.getByPath(jsonObj, "status");
            if (Objects.equals(status, 0)){
                Object lng = JSONUtil.getByPath(jsonObj, "result.location.lng");
                Object lat = JSONUtil.getByPath(jsonObj, "result.location.lat");
                Point point = new Point(Double.parseDouble(lng.toString()), Double.parseDouble(lat.toString()));
                return point;
            }else {
                log.error("geocoding error"+json);
            }
        } catch (Exception e) {
            log.error("baidugeo api error", e);
        }


        return null;
    }

    // 对Map内所有value作utf8编码，拼接返回结果
    public static String toQueryString(Map<?, ?> data)
            throws UnsupportedEncodingException {
        StringBuffer queryString = new StringBuffer();
        for (Map.Entry<?, ?> pair : data.entrySet()) {
            queryString.append(pair.getKey() + "=");
            queryString.append(URLEncoder.encode((String) pair.getValue(),
                    "UTF-8") + "&");
        }
        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1);
        }
        return queryString.toString();
    }

    // 来自stackoverflow的MD5计算方法，调用了MessageDigest库函数，并把byte数组结果转换成16进制
    public static String MD5(String md5) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest
                    .getInstance("MD5");
            byte[] array = md.digest(md5.getBytes());
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < array.length; ++i) {
                sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100)
                        .substring(1, 3));
            }
            return sb.toString();
        } catch (java.security.NoSuchAlgorithmException e) {
        }
        return null;
    }
}
